package org.xiaodongwei.jvm.op;

import org.xiaodongwei.jvm.exe.JVMStack;
import org.xiaodongwei.jvm.utils.ClassUtils;
import tech.medivh.classpy.classfile.bytecode.GetStatic;
import tech.medivh.classpy.classfile.bytecode.Instruction;
import tech.medivh.classpy.classfile.constant.ConstantPool;
import tech.medivh.classpy.classfile.jvm.Opcode;

import java.lang.reflect.Field;

public class GetStaticOpCodeExecute extends OpCodeExecute {

    public GetStaticOpCodeExecute(JVMStack jvmStack, ConstantPool constantPool) {
        opCode = Opcode.getstatic;
        this.jvmStack = jvmStack;
        this.constantPool = constantPool;
    }

    @Override
    public void execute(Instruction instruction) {
        // 获取一个静态对象, 从什么类中获取什么字段属性
        // JVM规范：获取一个属性，让后将其放到操作数栈中
        GetStatic getStatic = (GetStatic) instruction;
        String className = getStatic.getClassName(constantPool);
        String filedName = getStatic.getFieldName(constantPool);
        Object staticField;
        // 如果jvm类通过反射实现
        if (ClassUtils.isContainJava(className)) {
            try {
                // 我们通过反射的方式来实现, 通过className获取Clas对象，在调用Class对象的get获取对应的Filed对象
                // 最终将其push到操作数栈中
                Class<?> aClass = Class.forName(className);
                Field declaredField = aClass.getDeclaredField(filedName);
                staticField = declaredField.get(null);
                jvmStack.peek().pushToOperateStack(staticField);
            } catch (NoSuchFieldException e) {
                throw new RuntimeException(e);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
